#include "mcu_define.h"

int createServe(char const *ip,unsigned short port);
int createSocket(char const *ip,unsigned short port);
void mainloop(int servfd);
int handleData(int actfd);
void * sendmcu(void *arg);
void * sendsbjz(void *arg);
char p[512];
int main(int argc, char const *argv[])
{
    (void)argc;  // 显式忽略
    (void)argv;
    pthread_t tid2 = 0;
    memset(p,0,sizeof(p));
    int servfd =createServe(MCUIP,(unsigned short)MCUPORT);
    int ret = pthread_create(&tid2,NULL,sendsbjz,NULL);
    if (ret !=0)
       {
        ERROR("pthread_sendsbjz");
        exit(-1);
       }
    mainloop(servfd);
    return 0;
}

int createServe(char const *ip,unsigned short port){
    int sockfd =socket(AF_INET,SOCK_STREAM,0);
    if(sockfd ==-1){
        ERROR("socket");
        exit(-1);
    }
    printf("sockfd:%d\n",sockfd);
    struct sockaddr_in server_addr;
    server_addr.sin_family =AF_INET;
    server_addr.sin_port =htons(port);
    if(inet_aton(ip,&server_addr.sin_addr)==0){
        ERROR("inet_aton");
        exit(-1);
    }
    if(bind(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr))==-1){
        ERROR("bind");
        exit(-1);
    }
    if (listen(sockfd,20)==-1)
    {
        ERROR("listen");
        exit(-1);
    }
    return sockfd;
}
int createSocket(char const *ip, unsigned short port)
{
   int sockfd =socket(AF_INET,SOCK_STREAM,0);
   if (sockfd<0)
   {
    ERROR("socket");
    close(sockfd);
    exit(-1);
   }
   printf("sockfd:%d\n",sockfd);
   struct sockaddr_in server_addr;
 //  memset(&server_addr, 0, sizeof(server_addr));
   server_addr.sin_family =AF_INET;
   server_addr.sin_port =htons(port);
   if(inet_aton(ip,&server_addr.sin_addr)==0){
        ERROR("inet_aton");
        exit(-1);
    }
     
     if (connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr))==-1)
    {
       ERROR("connect");
       close(sockfd);
       exit(-1);
    }
    printf("connect to server successfully\n");
    return sockfd;
}
void mainloop(int servfd){
    struct sockaddr_in client_addr;
    socklen_t client_s =sizeof(client_addr);
    while (1)
    {   
        int actfd=accept(servfd,(struct sockaddr*)&client_addr,&client_s);
        if (actfd==-1)
        {
            ERROR("accept");
            exit(-1);
        }
        char *client_p=inet_ntoa(client_addr.sin_addr);
        printf("clientIP:%s connecting\n",client_p);
        
       pthread_t tid1 = 0;
       int ret = pthread_create(&tid1,NULL,sendmcu,&actfd);
       if (ret !=0)
       {
        ERROR("pthread_sendmcu");
        exit(-1);
       }

       ret = handleData(actfd);
        if(ret == 1){
            close(servfd);
            servfd =-1;
            break;
        }

    }
    
}
int handleData(int actfd){
      
       char buf[SHM_SIZE]={0};
       int  shmid, semid;
       struct shmseg *shm;

       // 创建信号量
    semid = semget(SEM_KEY, 1, 0666 | IPC_CREAT);
    if (semid == -1) {
        perror("semget");
        return 0;
    }

     // 初始化信号量为 1
    semctl(semid, 0, SETVAL, 1);
    //创建共享内存
   shmid = shmget(SHM_KEY, sizeof(struct shmseg), 0666 | IPC_CREAT);
    if (shmid == -1) {
        perror("shmget");
       return 0;
    }

    // 映射共享内存
    shm = (struct shmseg *) shmat(shmid, NULL, 0);
    if (shm == (void *) -1) {
        perror("shmat");
        return 0;
    }

       while (1)
       {
        memset(buf,0,sizeof(buf));
        int ret =recv(actfd,buf,sizeof(buf),0);
         if (ret==0)
        {
           printf("disconneted\n");
            close(actfd);
            actfd =-1;
            shmdt(shm);
           return 0;
        }
         if (ret<0)
        {
            ERROR("recv");
            exit(-1);
        }
       printf("buf:%s\n",buf);
       if(ret>0){
       memset(p,0,sizeof(p));
       strcpy(p, "{\"ONLINE\":1}");

       }
        sem_wait(semid);
         
        if (shm->written == 0) {
            strcpy(shm->text, buf);
            shm->written = 1;
            shm->read_flags[0] = 0;
            shm->read_flags[1] = 0;

        sem_signal(semid);
    }
       
  } 
}
void * sendmcu(void *arg){
     
       pthread_detach(pthread_self());
       int actfd = *(int *)arg;
       char buf[MSG_SIZE]={0};
       int msgid = msgget(MSG_KEY, 0666 | IPC_CREAT);
       struct msgbuf msg;
       while (1)
       {
        
        memset(buf,0,512);
       if (msgrcv(msgid, &msg, sizeof(msg.mtext), 0, 0) == -1) {
            ERROR("msg-error");
        }
        strcpy(buf,msg.mtext);
        int ret = send(actfd,buf,sizeof(buf),0);
        if(ret <=0){
         ERROR("sendtomcu");
         break;
        }
       
       }

       pthread_exit(NULL);
}
void * sendsbjz(void *arg){
    pthread_detach(pthread_self());
    int sockfd =createSocket(SB_IP,(unsigned short)SB_PORT);
   
    while (1)
    {
        if(strlen(p) >0){
        int ret =send(sockfd,p,sizeof(p),0);
        if (ret ==0)
        {
            printf("disconnected\n");
            break;
        }
        if (ret<0)
        {
            ERROR("send");
            close(sockfd);
            exit(-1);
        }
        if (ret>0)
        {
           printf("send sbss successfully\n");
           memset(p,0,sizeof(p));
        }
        }
        sleep(3);
        
    }
    pthread_exit(NULL);

}